package com.douqu.game.main.msg;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bean.core.buffer.ByteBuffer;
import com.douqu.game.core.controller.PlayerController;
import com.douqu.game.core.e.*;
import com.douqu.game.core.entity.Player;
import com.douqu.game.core.entity.activity.MatchBaseInfo;
import com.douqu.game.core.entity.battle.BattleDetail;
import com.douqu.game.core.entity.battle.BattleResultParamCampSingle;
import com.douqu.game.core.entity.battle.PlayerBattleData;
import com.douqu.game.core.entity.common.TwoTuple;
import com.douqu.game.core.entity.ext.BagInfo;
import com.douqu.game.core.entity.ext.ChallengeInfo;
import com.douqu.game.core.factory.CodeFactory;
import com.douqu.game.core.factory.ConfigFactory;
import com.douqu.game.core.factory.ConstantFactory;
import com.douqu.game.core.factory.DataFactory;
import com.douqu.game.core.netty.NettyConnection;
import com.douqu.game.core.protobuf.SGChallengeProto;
import com.douqu.game.core.protobuf.SGMainProto;
import com.douqu.game.core.util.CoreUtils;
import com.douqu.game.core.util.LogUtils;
import com.douqu.game.main.GameServer;
import com.douqu.game.main.server.ActivityCampManager;
import com.douqu.game.main.server.ServerManager;
import com.douqu.game.main.server.SpringContext;
import com.douqu.game.main.server.entity.ServerInfo;
import com.douqu.game.main.server.entity.ServerInfoBattle;
import com.douqu.game.main.service.PlayerService;
import com.douqu.game.main.util.MsgUtils;
import io.netty.buffer.ByteBuf;

import java.util.List;

/**
 * Created by bean on 2017/7/21.
 */
public class ServerMsgChannel {


    public static void messageChannel(int code, NettyConnection connection, ByteBuf byteBuf)
    {
        ServerManager serverManager = ServerManager.getInstance();
        if(CodeFactory.GET_BATTLE_SERVER_PORT == code)
        {
            int port = ServerManager.getInstance().getBattleServerPort();
            LogUtils.info("TCP战斗服务器获取端口:"+ port + "  ip:" + connection.getChannel().remoteAddress());

            ByteBuffer out = new ByteBuffer();
            out.writeInt(port);
            connection.sendMsg(code, out.getBytes());

            serverManager.addServerInfo(E_ServerType.BATTLE, connection, port);
        }
        else if(code == CodeFactory.START_BATTLE_TCP_SERVER)
        {
            if(connection.getObject() == null || !(connection.getObject() instanceof ServerInfoBattle))
            {
                LogUtils.error("非法数据");
                return;
            }
            LogUtils.warn("战斗服务器已经启动:"+connection);
            ServerInfoBattle serverInfo = (ServerInfoBattle) connection.getObject();
            if(serverInfo != null)
            {
                LogUtils.warn("TCP战斗服务器开启，设置运行:" + serverInfo);

                serverInfo.setRunning(true);

                ByteBuffer out = new ByteBuffer();
                out.writeBoolean(true);
                connection.sendMsg(code, out.getBytes());
            }
        }
        else if(code == CodeFactory.BATTLE_PING_MAIN)
        {
            LogUtils.debug("收到战斗服务器发来的PING消息 -> ");
            ByteBuffer buffer = CoreUtils.toByteBuffer(byteBuf);

            if(buffer.available() > 0)
            {
                int serverId = buffer.readInt();
                ServerInfo serverInfo = ServerManager.getInstance().getBattleServerInfo(serverId);
                if(serverInfo != null && serverInfo instanceof ServerInfoBattle)
                {
                    String battleId = buffer.readUTF();
                    ServerInfoBattle serverInfoBattle = (ServerInfoBattle) serverInfo;
                    BattleDetail battleDetail = serverInfoBattle.getBattle(battleId);
                    if(battleDetail != null)
                    {
                        PlayerController playerController = GameServer.getInstance().getWorldManager().getPlayerController(battleDetail.getTeam1Info().getIndexInfo());
                        if(playerController != null)
                            playerController.setLastUpdate(DataFactory.currentTime, 0, E_PlayerLastUpdate.BATTLE_PING);
                    }
                }
            }
        }
        else if(CodeFactory.ACTIVITY_SERVER_INIT == code)
        {
            LogUtils.info("活动服务器初始化成功,现在告诉它RMI地址");

            ByteBuffer buffer = CoreUtils.toByteBuffer(byteBuf);
            //接收到的公共数据
            JSONObject jsonObject = JSONObject.parseObject(buffer.readUTF());

            LogUtils.warn("活动服务器初始化发来的数据->" + jsonObject);

            boolean flag = ActivityCampManager.getInstance().init(jsonObject);
            LogUtils.info(jsonObject.getString(ConstantFactory.FIRST_CAMP_PLAYER_LIST));
            List<String> firstCampPlayerList = JSONObject.parseArray(jsonObject.getString(ConstantFactory.FIRST_CAMP_PLAYER_LIST), String.class);
//            ActivityCampManager.getInstance().init(jsonObject.getString(ConstantFactory.ACTIVITY_INDEX),
//                                                   jsonObject.getString(ConstantFactory.ACTIVITY_STATUS),
//                                                   jsonObject.getString(ConstantFactory.ACTIVITY_SERVER_HTTP),
//                                                   JSONObject.parseObject(jsonObject.getString(ConstantFactory.MAX_WIN_COUNT_PLAYER), RankPlayer.class),
//                                                   JSONObject.parseObject(jsonObject.getString(ConstantFactory.MAX_CONTINUE_WIN_PLAYER), RankPlayer.class),
//                                                   JSONObject.parseObject(jsonObject.getString(ConstantFactory.MAX_EXPLOIT_PLAYER), RankPlayer.class),
//                                                   JSONObject.parseArray(jsonObject.getString(ConstantFactory.RANK_PLAYER_LIST), RankPlayer.class),
//                                                   JSONObject.parseArray(jsonObject.getString(ConstantFactory.RANK_CAMP_LIST), RankCamp.class),
//                                                   JSONObject.parseArray(jsonObject.getString(ConstantFactory.APPLY_PLAYER_LIST), String.class));

            ByteBuffer out = new ByteBuffer();
            out.writeUTF(ConfigFactory.SERVER_URL_RMI);
            out.writeBoolean(flag);
            connection.sendMsg(code, out.getBytes());

            serverManager.addServerInfo(E_ServerType.ACTIVITY, connection, 0);
        }
        else if(CodeFactory.ACTIVITY_CAMP_APPLY_SUCCESS == code)
        {
            ByteBuffer buffer = CoreUtils.toByteBuffer(byteBuf);
            String playerIndex = buffer.readUTF();
            E_ApplyCampActivityType type = E_ApplyCampActivityType.valueOf(buffer.readUTF());

            LogUtils.info("主服务器收到活动服回复的报名成功的消息 -> 玩家ID:" + playerIndex + ", type:" + type);
            PlayerController playerController = GameServer.getInstance().getWorldManager().getPlayerController(playerIndex);
            if(type == E_ApplyCampActivityType.DEFAULT && playerController != null)
            {
                playerController.sendMsg(SGMainProto.E_MSG_ID.MsgID_Activity_CampApply_VALUE, null);
            }
        }
        else if(CodeFactory.ACTIVITY_CAMP_MATCH_SUCCESS == code)
        {
            ByteBuffer buffer = CoreUtils.toByteBuffer(byteBuf);
            JSONObject jsonObject = JSONObject.parseObject(buffer.readUTF());
            String playerIndex = jsonObject.getString(CodeFactory.KEY_PLAYER_INDEX);
            String teamIndex = jsonObject.getString(CodeFactory.KEY_TEAM_INDEX);
            E_MatchType matchType = E_MatchType.valueOf(jsonObject.getString("matchType"));
            MatchBaseInfo targetInfo = JSONObject.parseObject(jsonObject.getString("target"), MatchBaseInfo.class);

            LogUtils.info("主服务器收到阵营战匹配成功的消息,现在确定玩家的状态 -> teamIndex:" + teamIndex + ", playerIndex:" + playerIndex);

            TwoTuple<Player, PlayerController> playerResult = GameServer.getInstance().getWorldManager().getPlayerResult(playerIndex);
            PlayerController playerController = playerResult.getSecond();
            if(playerController == null)
            {
                LogUtils.info("匹配的玩家不在线 -> playerIndex:" + playerIndex + " matchType:" + matchType);
                //结算并保存数据
                Player player = playerResult.getFirst();
                if(player == null)
                {
                    LogUtils.error("玩家不存在,请检查数据 -> " + playerIndex);
                    return;
                }

                if(matchType == E_MatchType.ROBOT)
                {
                    BattleResultParamCampSingle resultParam = ActivityCampManager.getInstance().directEndCampBattle(player.fc>targetInfo.getFc(), player, targetInfo, null);
                    //回复活动服
                    replyMatchSuccess(connection, teamIndex, playerIndex, false, false, resultParam);

//                    player.getCampBattleData().addMatch(targetInfo.getObjectIndex());

                    if(resultParam.getAddExploit() > 0)
                        GameServer.getInstance().savePlayerSync(player, false, ChallengeInfo.class, BagInfo.class);
                    else
                        GameServer.getInstance().savePlayerSync(player, false, ChallengeInfo.class);
                }
                else if(matchType == E_MatchType.PLAYER)
                {
                    //回复活动服
                    replyMatchSuccess(connection, teamIndex, playerIndex, true, false, null);
                }
            }
            else
            {
                //玩家在线
                if(!playerController.isFree() || playerController.getTcpConnection() == null)
                {
                    if(matchType == E_MatchType.ROBOT)
                    {
                        //回复活动服
                        replyMatchSuccess(connection, teamIndex, playerIndex, false, false,
                                ActivityCampManager.getInstance().directEndCampBattle(
                                        playerController.getPlayer().fc>targetInfo.getFc(), playerController.getPlayer(), targetInfo, null));
                    }
                    else if(matchType == E_MatchType.PLAYER)
                    {
                        //回复活动服
                        replyMatchSuccess(connection, teamIndex, playerIndex, true, false, null);
                    }
                }
                else
                {
                    //通知玩家开始倒计时10秒
                    //回复活动服
                    replyMatchSuccess(connection, teamIndex, playerIndex, true, true, null);

                    playerController.setStatus(E_PlayerStatus.CAMP_BATTLE_MATCH_SUCCESS);
//                    playerController.sendWarn("匹配成功,10秒后进入战斗!");
                    sendCampActivityCountdown(playerController);
                }

//                playerController.getPlayer().getCampBattleData().addMatch(targetInfo.getObjectIndex());
            }
        }
        else if(CodeFactory.ACTIVITY_CAMP_START_BATTLE == code)
        {
            LogUtils.info("活动服务器通知主服务器已经可以连接战斗服务器了,现在通知玩家!");

            try{
                ByteBuffer buffer = CoreUtils.toByteBuffer(byteBuf);
                JSONObject jsonObject = JSONObject.parseObject(buffer.readUTF());
                String playerIndex = jsonObject.getString(CodeFactory.KEY_PLAYER_INDEX);
                String battleId = jsonObject.getString(CodeFactory.KEY_BATTLE_ID);
//                int battleTypeInt = jsonObject.getInteger(CodeFactory.KEY_BATTLE_TYPE);
//                SGCommonProto.E_BATTLE_TYPE battleType = SGCommonProto.E_BATTLE_TYPE.forNumber(battleTypeInt);
                int battleDetailTypeInt = jsonObject.getInteger(CodeFactory.KEY_BATTLE_DETAIL_TYPE);
                E_BattleDetailType battleDetailType = E_BattleDetailType.forNumber(battleDetailTypeInt);
                String battleServerHost = jsonObject.getString(CodeFactory.KEY_BATTLE_SERVER_HOST);
                int battleServerPort = jsonObject.getInteger(CodeFactory.KEY_BATTLE_SERVER_PORT);
                MatchBaseInfo playerBase = JSONObject.parseObject(jsonObject.getString(CodeFactory.KEY_TARGET), MatchBaseInfo.class);

                PlayerController playerController = GameServer.getInstance().getWorldManager().getPlayerController(playerIndex);
                if(playerController == null)
                {
                    PlayerService playerService = SpringContext.getBean(PlayerService.class);
                    Player player = new Player(playerService.getPlayerByIndex(playerIndex));
                    if(player == null)
                    {
                        LogUtils.error("1玩家不存在,请检查数据 -> " + playerIndex);
                        return;
                    }

                    LogUtils.error("玩家已经不在线,重新加入报名列表 -> " + playerIndex + "," + player.name);
                    ServerManager.getInstance().sendApplyActivity(player, E_ApplyCampActivityType.BATTLE_INIT_OFFLINE);
                    return;
                }

                if(playerController.getStatus() == E_PlayerStatus.WAIT_BATTLE_CREATE)
                {
                    LogUtils.info("已经请求过战斗,等待创建 -> " + playerController.getName());
                    return;
                }

                PlayerBattleData battleData = new PlayerBattleData(battleId, battleDetailType, battleServerHost, battleServerPort);
                playerController.setBattleData(battleData);
                playerController.setStatus(E_PlayerStatus.WAIT_BATTLE_CREATE);

                MsgUtils.sendSpanCampBattle(playerController, battleId, battleServerHost, battleServerPort, playerBase);
            }catch (Exception e){
                e.printStackTrace();
                LogUtils.error("接收匹配成功消息参数错误!");
            }
        }
        else if(CodeFactory.ACTIVITY_CAMP_STATUS == code)
        {
            ByteBuffer buffer = CoreUtils.toByteBuffer(byteBuf);
            JSONObject jsonObject = JSON.parseObject(buffer.readUTF());
            String index = jsonObject.getString(CodeFactory.KEY_INDEX);
            E_ActivityCampStatus status = E_ActivityCampStatus.valueOf(jsonObject.getString(CodeFactory.KEY_STATUS));

            LogUtils.warn("收到阵营战活动状态消息 -> index:" + index + " status:" + status);

            ActivityCampManager.getInstance().setStatus(status);
            ActivityCampManager.getInstance().setIndex(index);

            if(status == E_ActivityCampStatus.CLEAR_ING)
            {
                ActivityCampManager.getInstance().end(jsonObject);
                ByteBuffer out = new ByteBuffer();
                out.writeBoolean(true);
                connection.sendMsg(code,out.getBytes());
            }
            else if(status == E_ActivityCampStatus.RUN_ING)
            {
                //活动开始
                ActivityCampManager.getInstance().start(jsonObject);
            }
        }
        else if(CodeFactory.ACTIVITY_CAMP_RANK_INFO == code)
        {
            LogUtils.info("收到活动服务器发来的最新排行信息");

            ByteBuffer buffer = CoreUtils.toByteBuffer(byteBuf);
            //接收到的公共数据
            JSONObject jsonObject = JSONObject.parseObject(buffer.readUTF());

            ActivityCampManager.getInstance().update(jsonObject);
        }
        else if(CodeFactory.ACTIVITY_CAMP_TIME == code)
        {
            LogUtils.info("收到活动服务器发来的活动时间");

            ByteBuffer buffer = CoreUtils.toByteBuffer(byteBuf);
            //接收到的公共数据
            JSONObject jsonObject = JSONObject.parseObject(buffer.readUTF());

            ActivityCampManager.getInstance().initTime(jsonObject);
        }
    }


    /**
     *
     * @param connection
     * @param playerIndex
     * @param flag 是否可以进行下一步
     * @param resultParam
     */
    public static void replyMatchSuccess(NettyConnection connection, String teamIndex, String playerIndex, boolean flag, boolean free, BattleResultParamCampSingle resultParam)
    {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put(CodeFactory.KEY_PLAYER_INDEX, playerIndex);
        jsonObject.put(CodeFactory.KEY_TEAM_INDEX, teamIndex);
        jsonObject.put(CodeFactory.KEY_FLAG, flag);
        jsonObject.put(CodeFactory.KEY_FREE, free);
        if(resultParam != null)
            jsonObject.put(CodeFactory.KEY_RESULT, resultParam);

        ByteBuffer out = new ByteBuffer();
        out.writeUTF(jsonObject.toJSONString());
        connection.sendMsg(CodeFactory.ACTIVITY_CAMP_MATCH_SUCCESS, out.getBytes());
    }

    public static void sendCampActivityCountdown(PlayerController playerController)
    {
        SGChallengeProto.S2C_CampCountdown.Builder response = SGChallengeProto.S2C_CampCountdown.newBuilder();
        response.setTime(10);
        playerController.sendMsg(SGMainProto.E_MSG_ID.MsgID_Activity_CampCountdown_VALUE, response.build().toByteArray());
    }



}
